home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / utils / clocks / sunclock.zoo / SOURCES / SUNCLOCK.C < prev    next >
C/C++ Source or Header  |  1990-06-08  |  21KB  |  791 lines

  1. /*
  2.     ATARI-ST clock    by Joep Mathijssen
  3.  
  4.     Original header:
  5.     ---------------
  6.  
  7.     Sun clock
  8.  
  9.     Designed and implemented by John Walker in November of 1988.
  10.  
  11.     Version for the Sun Workstation.
  12.  
  13.     The algorithm used to calculate the position of the Sun is given in
  14.     Chapter 18 of:
  15.  
  16.     "Astronomical  Formulae for Calculators" by Jean Meeus, Third Edition,
  17.     Richmond: Willmann-Bell, 1985.  This book can be obtained from:
  18.  
  19.        Willmann-Bell
  20.        P.O. Box 35025
  21.        Richmond, VA  23235
  22.        USA
  23.        Phone: (804) 320-7016
  24.  
  25.     This program was written by:
  26.  
  27.        John Walker
  28.        Autodesk, Inc.
  29.        2320 Marinship Way
  30.        Sausalito, CA  94965
  31.        USA
  32.        Fax:   (415) 389-9418
  33.        Voice: (415) 332-2344 Ext. 2829
  34.        Usenet: {sun,well,uunet}!acad!kelvin
  35.        or: kelvin@acad.uu.net
  36.  
  37.     This  program is in the public domain: "Do what thou wilt shall be the
  38.     whole of the law".  I'd appreciate  receiving  any  bug  fixes  and/or
  39.     enhancements,  which  I'll  incorporate  in  future  versions  of  the
  40.     program.  Please leave the original attribution information intact    so
  41.     that credit and blame may be properly apportioned.
  42.  
  43.     Revision history:
  44.  
  45.     1.0  12/21/89  Initial version.
  46.           8/24/89  Finally got around to submitting.
  47.  
  48. */
  49.  
  50. #include <stdio.h>
  51. #include <stdlib.h>
  52. #include <ctype.h>
  53. #include <string.h>
  54. #include <math.h>
  55. #include <time.h>
  56. #include <assert.h>
  57. #include <tos.h>
  58. #include <vdi.h>
  59. #include <aes.h>
  60.  
  61. #include "gem.h"
  62. #include "dialog.h"
  63. #include "scr2.h"
  64. #include "sunclock.img"              /* Icon and open window bitmaps */
  65. #include "sunclock.h"                            /* .RCS-file */
  66.  
  67. /*----- Prototypes -----*/
  68. void pw_setmode( int );
  69. void pw_vector( void*, int, int, int, int, int, int );
  70. void pw_b_on( void* );
  71. void pw_b_off( void* );
  72. void updimage( int );
  73. void timer_proc( void );
  74. static void   cevent( void );
  75. static long   jdate( struct tm* );
  76. static double jtime( struct tm* );
  77. static double kepler( double, double );
  78. static void   sunpos( double, int, double*, double*, double*, double* );
  79. static double gmst( double );
  80. static void projillum( short*, int, int, double );
  81. static void xspan( int, int, int );
  82. static void moveterm( short*, int, short*, int, int, int );
  83.  
  84. OBJECT  *dialog_addr;
  85. bool    bufferio;
  86.  
  87. #define abs(x) ((x) < 0 ? (-(x)) : x)              /* Absolute value */
  88. #define sgn(x) (((x) < 0) ? -1 : ((x) > 0 ? 1 : 0))      /* Extract sign */
  89. #define dtr(x) ((x) * (PI / 180.0))              /* Degree->Radian */
  90. #define rtd(x) ((x) / (PI / 180.0))              /* Radian->Degree */
  91. #define fixangle(a) ((a) - 360.0 * (floor((a) / 360.0)))  /* Fix angle      */
  92.  
  93. #define V      (void)
  94.  
  95. #define PI 3.14159265358979323846
  96.  
  97. #define TERMINC  100           /* Circle segments for terminator */
  98.  
  99. #define PROJINT  (60 * 10)       /* Frequency of seasonal recalculation
  100.                       in seconds. */
  101.  
  102. #define OXDOTS     640           /* Open window width */
  103. #define OYDOTS     320          /* Open window height */
  104.  
  105. /*  Globals imported  */
  106.  
  107. extern time_t time();
  108.  
  109. /*  Local variables  */
  110.  
  111. static int xdots, ydots;       /* Screen size */
  112.  
  113. static char *wdname[] = {       /* Week day names */
  114.         "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
  115. };
  116.  
  117. static int onoon = -1;
  118. static short *wtab, *wtab1, *wtabs;
  119.  
  120. static int fdate = FALSE, idir = 1, animate = FALSE;
  121. static long lincr = 3600;
  122. static long cctime;
  123.  
  124. /*  Forward procedures    */
  125.  
  126. double jtime(), gmst();
  127. void drawterm(), sunpos(), projillum(), moveterm(), outdiff();
  128.  
  129.  
  130. /*  PW_MODE: GEM-version */
  131. #define PIX_SRC     0x01
  132. #define PIX_DST     0x02
  133. #define PIX_NOT     ~
  134.  
  135. /* Used in pw_vector. Not complete! */
  136. void pw_setmode(pw_mode)
  137. int pw_mode;
  138. {
  139.     int gemmode = 1;
  140.     
  141.     switch (pw_mode) {
  142.     case PIX_SRC ^ PIX_DST:
  143.         gemmode = 3;
  144.         break;
  145.     }
  146.     vswr_mode(handle, gemmode);
  147. }
  148.  
  149. /* PW_VECTOR: draw a line using gem. Could draw directly to screen or
  150.               by a Aline for speed, but this is easier */
  151. void pw_vector(pw, x1, y1, x2, y2, mode, color)
  152. void    *pw;
  153. int     x1, x2, y1, y2, mode, color;
  154. {
  155.     pw_setmode(mode); 
  156.     vsl_color(handle, color);
  157.     pxyarray[0] = x1;
  158.     pxyarray[1] = y1;
  159.     pxyarray[2] = x2;
  160.     pxyarray[3] = y2;
  161.     v_pline(handle,2,pxyarray);
  162. }
  163.  
  164. /* PW_BATCH_ON/OFF: use define to avoid double define because of 
  165.                     8 chars limit */
  166. #define pw_batch_on pw_b_on
  167. void pw_b_on(pw)
  168. void    *pw;
  169. {
  170.     Scr2Init();
  171.     Scr2Copy();
  172. }
  173.  
  174. #define pw_batch_off pw_b_off
  175. void pw_b_off(pw)
  176. void    *pw;
  177. {
  178.     Scr2Swap();
  179.     Scr2Exit();
  180. }
  181.  
  182. /*  UPDIMAGE  --  Update current displayed image.  */
  183. static void updimage(istimer)
  184. int istimer;
  185. {
  186.     int i, xl;
  187.     struct tm *ct;
  188.     char tbuf[100];
  189.     double jt, sunra, sundec, sunrv, sunlong, gt;
  190.     struct tm lt;
  191.     static int lisec = 61;       /* Last iconic seconds */
  192.     static long lctime = 0;    /* Last full calculation time */
  193.     static  int *cpw;
  194.  
  195.     if (!istimer) {
  196.           xdots = OXDOTS;
  197.           ydots = OYDOTS;
  198.  
  199.           cpw = Logbase();
  200.           for (i=0 ; i < sizeof(bimg)/sizeof(int) ; i++)
  201.               cpw[i] = ~(bimg[i]);
  202.           for (; i < 16000 ; i++)
  203.               cpw[i] = 0xFFFF;
  204.     }
  205.  
  206.     /* If this is a full repaint of the window, force complete
  207.        recalculation. */
  208.  
  209.     if (!istimer) {
  210.        lctime = 0;
  211.        onoon = -1;
  212.        lisec = 61;
  213.        for (i = 0; i < OYDOTS; i++)
  214.           wtab1[i] = -1;
  215.     }
  216.  
  217.     if (fdate) {
  218.        if (animate)
  219.           cctime += lincr;
  220.        if (cctime < 0)
  221.           cctime = 0;
  222.     } else {
  223.        V time(&cctime);
  224.     }
  225.     lt = *localtime(&cctime);
  226.  
  227.     ct = gmtime(&cctime);
  228.  
  229.     jt = jtime(ct);
  230.     sunpos(jt, FALSE, &sunra, &sundec, &sunrv, &sunlong);
  231.     gt = gmst(jt);
  232.  
  233.     /* Projecting the illumination curve  for the current seasonal
  234.            instant is costly.  If we're running in real time, only  do
  235.        it every PROJINT seconds.  */
  236.  
  237.     if (fdate || !istimer || ((cctime - lctime) > PROJINT)) {
  238.        projillum(wtab, xdots, ydots, sundec);
  239.        wtabs = wtab;
  240.        wtab = wtab1;
  241.        wtab1 = wtabs;
  242.        lctime = cctime;
  243.     }
  244.  
  245.     sunlong = fixangle(180.0 + (sunra - (gt * 15)));
  246.     xl = sunlong * (xdots / 360.0);
  247.  
  248.     /* If the subsolar point has moved at least one pixel, update
  249.        the illuminated area on the screen.    */
  250.  
  251.     if (fdate || !istimer || (onoon != xl)) {
  252.        if (bufferio) 
  253.            pw_batch_on(0);
  254.        moveterm(wtab1, xl, wtab, onoon, xdots, ydots);
  255.        if (bufferio) 
  256.            pw_batch_off(0);
  257.        onoon = xl;
  258.     }
  259.  
  260.     /* Display time */
  261.     sprintf(tbuf, "\033p\033Y%c%c%02d:%02d:%02d %s %02d/%02d/%02d",
  262.             ' '+22, ' '+7,
  263.             lt.tm_hour, lt.tm_min, 2*lt.tm_sec,
  264.             wdname[lt.tm_wday],
  265.             lt.tm_mon + 1, lt.tm_mday, (lt.tm_year % 100));
  266.     puts(tbuf);
  267.  
  268.     /* Display mode */
  269.     sprintf(tbuf, "\033p\033Y%c%c(", ' '+23, ' '+7);
  270.     strcat(tbuf, (animate) ? "Animate" : "Real time" );
  271.     if (animate) {
  272.         strcat(tbuf, (idir < 0) ? ", <<" : ", >>");
  273.         switch (abs(lincr)) {
  274.         case 3600L:
  275.            strcat(tbuf, " hour");
  276.            break;
  277.         case 86400L:
  278.            strcat(tbuf, " day");
  279.            break;
  280.         case 604800L:
  281.            strcat(tbuf, " week");
  282.            break;
  283.         case 2592000L:
  284.            strcat(tbuf, " month");
  285.            break;
  286.         case 31536000L:
  287.            strcat(tbuf, " year");
  288.            break;
  289.         }
  290.     }
  291.     strcat(tbuf, ")");
  292.     puts(tbuf);
  293.  
  294.     /* Display credits */
  295.     printf("\033p\033Y%c%cSUN   : John Walker, Autodesk, Inc.", ' '+22, ' '+40);
  296.     printf("\033p\033Y%c%cATARI : Joep Mathijssen", ' '+23, ' '+40);
  297. }
  298.  
  299. /*  Frame event processor  
  300. static frame_event_proc(frame, event, arg, type)
  301. Frame frame;
  302. Event *event;
  303. Notify_arg arg;
  304. Notify_event_type type;
  305. {
  306.     switch (event_id(event)) {
  307.  
  308.        case WIN_REPAINT:
  309.           if (window_get(bf, FR